package it.univaq.di.helpdesk.presentation;

import it.univaq.di.helpdesk.business.common.DeviceService;
import it.univaq.di.helpdesk.business.common.HelpDeskServiceFactory;
import it.univaq.di.helpdesk.business.common.TicketService;
import it.univaq.di.helpdesk.business.common.UserService;
import it.univaq.di.helpdesk.business.model.Attachment;
import it.univaq.di.helpdesk.business.model.AttachmentData;
import it.univaq.di.helpdesk.business.model.Category;
import it.univaq.di.helpdesk.business.model.Comment;
import it.univaq.di.helpdesk.business.model.Computer;
import it.univaq.di.helpdesk.business.model.Device;
import it.univaq.di.helpdesk.business.model.Office;
import it.univaq.di.helpdesk.business.model.Priority;
import it.univaq.di.helpdesk.business.model.Status;
import it.univaq.di.helpdesk.business.model.Ticket;
import it.univaq.di.helpdesk.business.model.User;
import it.univaq.di.helpdesk.business.model.UserProfile;
import it.univaq.di.helpdesk.common.utils.AjaxResponse;
import it.univaq.di.helpdesk.common.utils.JavaMailHelper;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;
import org.apache.struts.upload.FormFile;

public class ManageTicketAction extends MappingDispatchAction {
	
	public ActionForward activeaddticket(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		UserService userService = factory.getUserService();
		DeviceService deviceService = factory.getDeviceService();
		
		User user = (User) request.getSession().getAttribute("user");  
		
		int userID = user.getUserID();
		
		List<Category> categories = service.findParentCategories();
		List<Priority> priorities = service.findPriorities();
		List<User> technics = userService.findAllTechnics();
		List<Device> devices = deviceService.findDeviceByUserId(userID);
		
		// Recupero nuovamente l'utente perchè quello in sessione non ha le relazioni complete
		User completeUser = userService.findUserByID(user.getUserID());
		// Si da la possibilità ad un utente di aprire ticket per i device associati all'ufficio in cui lavora
		Office userOffice = completeUser.getOffice();
		if (userOffice!=null) {
			List<Device> officeDevices = userOffice.getDevices();
			devices.addAll(officeDevices);
		}
		
		request.setAttribute("categories", categories);
		request.setAttribute("priorities", priorities);
		request.setAttribute("technics", technics);
		request.setAttribute("devices", devices);
		
		// Salvataggio del token riutilizzato nel metodo addticket.
		saveToken(request);
		
		return mapping.findForward("ticket.activeaddticket");
	}
	
	/* AJAX Request */
	public ActionForward loadsubcategories(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		String catID = request.getParameter("catID");
		if(catID.isEmpty()) {
			catID = "0";
		}
		
		List<Category> categories = service.findSubCatgories(Integer.parseInt(catID));
		
		AjaxResponse ajaxResponse = AjaxResponse.getInstance();
		ajaxResponse.sendJson(categories, response.getWriter());
		
		return null;
	}
	
	/* AJAX Request */
	public ActionForward addticket(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
	
		/* controlla se il token inserito in sessione dal metodo activeaddticket
		 * è valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}	

		Ticket ticket = new Ticket();
		TicketForm ticketForm = (TicketForm)actionForm;

		BeanUtils.copyProperties(ticket, ticketForm);
		
		ticket.setOpenBy((User)request.getSession().getAttribute("user"));
		User technic = new User();
		technic.setUserID(ticketForm.getAssignedId());
		ticket.setAssignedTo(technic);
		ticket.setOpenDate(new Date());
		
		Priority priority = new Priority();
		priority.setName(ticketForm.getPriorityName());
		ticket.setPriority(priority);
		
		Status status = new Status();
		status.setName("Open");
		ticket.setStatus(status);
		
		Category subCat = new Category();
		subCat.setCategoryID(ticketForm.getSubCategoryID());
		ticket.setSubCategory(subCat);
		
		Device computer = new Computer();
		computer.setDeviceID(ticketForm.getDeviceID());
		ticket.setDevice(computer);

		List<Attachment> attachments = new ArrayList<Attachment>();
		
		for(FormFile file: ticketForm.getFormFiles()) {
			if(!file.getFileName().isEmpty()) {
				Attachment attachment = new Attachment();
				attachment.setFileName(file.getFileName());
				attachment.setFileSize(file.getFileSize());
				attachment.setFileContentType(file.getContentType());
				
				AttachmentData attachmentData = new AttachmentData();
				attachmentData.setFileData(file.getFileData());
				
				attachment.setAttachmentData(attachmentData);
				attachments.add(attachment);
			}
		}
		
		ticket.setAttachment(attachments);
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		service.addTicket(ticket);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		if (ticketForm.isSendmail()) {
			JavaMailHelper mailer = JavaMailHelper.getInstance();
			//TODO i messaggi andrebbero generati mediante un template
			mailer.sendMail(ticketForm.getEmail(), ticket.getSubject(), ticket.getDescription());
		}
		
		UserService userService = factory.getUserService();
		User user = userService.findUserByID(ticket.getAssignedTo().getUserID());
		UserProfile userProfile = user.getProfile(); 
		if (userProfile != null && userProfile.isEnableNotice()) {
			JavaMailHelper mailer = JavaMailHelper.getInstance();
			
			mailer.sendMail(user.getEmail(), ticket.getSubject(), ticket.getDescription());
		}
		
		return mapping.findForward("common.ok");
	}
	
	/* AJAX Request */
	public ActionForward viewtickethistory(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
	
		List<Status> status = service.findStatus();
		request.setAttribute("status", status);
		
		List<Priority> priorities = service.findPriorities();
		request.setAttribute("priorities", priorities);
		
		return mapping.getInputForward();
	}
	
	/* AJAX Request */
	public ActionForward getticketlist (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		User user = (User)request.getSession().getAttribute("user");
		
		TicketHistoryForm form = (TicketHistoryForm) actionForm;
		
		Map<String, String> queryParam = new HashMap<String, String>();
		queryParam.put("openby", Integer.toString(user.getUserID()));
		queryParam.put("priority", form.getPriorityType());
		queryParam.put("status", form.getStatusType());
		queryParam.put("contains", form.getContains());
		
		List<Ticket> tickets = service.findTicketList(queryParam);
		request.setAttribute("tickets", tickets);
		
		return mapping.findForward("ticket.getticketlist");
	}
	
	/* AJAX Request */
	public ActionForward getoperatorticketlist (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		User user = (User)request.getSession().getAttribute("user");
		
		TicketHistoryForm form = (TicketHistoryForm) actionForm;
		
		Map<String, String> queryParam = new HashMap<String, String>();
		queryParam.put("assignedto", Integer.toString(user.getUserID()));
		queryParam.put("priority", form.getPriorityType());
		queryParam.put("status", form.getStatusType());
		queryParam.put("contains", form.getContains());
		
		List<Ticket> tickets = service.findTicketList(queryParam);
		request.setAttribute("tickets", tickets);
		
		List<Status> status = service.findStatus();
		request.setAttribute("status", status);
		
		List<Priority> priorities = service.findPriorities();
		request.setAttribute("priorities", priorities);
				
		return mapping.findForward("operator.getoperatorticketlist");
	}
	
	/* AJAX Request */
	public ActionForward loadticketnote(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		NoteForm form = (NoteForm) actionForm;
		
		int ticketID = Integer.parseInt(request.getParameter("ticketID"));
		
		form.setTicketID(Integer.toString(ticketID));
		
		List<Comment> comments = service.findCommentsByTicketId(ticketID);
		request.setAttribute("comments", comments);
		
		return mapping.getInputForward();
	}
	
	
	/* AJAX Request */
	public ActionForward addticketnote(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		Comment comment = new Comment();
		
		NoteForm form = (NoteForm) actionForm;
		
		int ticketID = Integer.parseInt(form.getTicketID());
		comment.setTicketID(ticketID);
		comment.setContent(form.getCommentText());
		comment.setCommentDate(new Date());
		
		User user = (User)request.getSession().getAttribute("user");
		comment.setWrittenBy(user);
		
		service.addComment(comment);
		
		Ticket ticket = service.findTicketById(ticketID);
		User notifyTo = null;
		if (request.isUserInRole("operator")) {
			notifyTo = ticket.getOpenBy();	
		} else {
			notifyTo = ticket.getAssignedTo();
		}
		
		UserProfile userProfile = notifyTo.getProfile(); 
		if (userProfile != null && userProfile.isEnableNotice()) {
			JavaMailHelper mailer = JavaMailHelper.getInstance();
			//TODO i messaggi andrebbero generati mediante un template
			mailer.sendMail(notifyTo.getEmail(), "HelpDesk - New comment Added", comment.getContent());
		}
		
		return null;
	}
	
	/* AJAX Request */
	public ActionForward activeticketattachment(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {		
		
		AttachmentForm attachmentForm = (AttachmentForm) actionForm;			
		attachmentForm.setTicketID(request.getParameter("itemID"));
		
		request.setAttribute("ticketID", request.getParameter("itemID"));
		
		// Salvataggio del token riutilizzato nel metodo addticketattachment.
		saveToken(request);
		
		return mapping.findForward("ticket.activeticketattachment");
	}
	
	/* AJAX Request */
	public ActionForward addticketattachment(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
	
		
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}	
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
				
		
		AttachmentForm attachmentForm = (AttachmentForm) actionForm;	
		FormFile file = attachmentForm.getAttachmentFile();
		int ticketID = Integer.parseInt(attachmentForm.getTicketID());
		
		Attachment attachment = new Attachment();
		
		attachment.setTicketID(ticketID);
		
		attachment.setFileName(file.getFileName());
		attachment.setFileSize(file.getFileSize());
		attachment.setFileContentType(file.getContentType());
		
		AttachmentData attachmentData = new AttachmentData();
		attachmentData.setFileData(file.getFileData());
		
		attachment.setAttachmentData(attachmentData);
		
		service.addAttachment(attachment);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		// Recupera il messaggio di corretto salvataggio utilizzando la localizzazione
		/*ResourceBundle resource = ResourceBundle.getBundle("it.univaq.di.helpdesk.locales.Main", request.getLocale());
		String msg = (String) resource.getObject("message.ok");
		*/
		
		Ticket ticket = service.findTicketById(ticketID);
		User notifyTo = null;
		if (request.isUserInRole("operator")) {
			notifyTo = ticket.getOpenBy();
		} else {
			notifyTo = ticket.getAssignedTo();
		}
		
		UserProfile userProfile = notifyTo.getProfile(); 
		if (userProfile != null && userProfile.isEnableNotice()) {
			JavaMailHelper mailer = JavaMailHelper.getInstance();
			//TODO i messaggi andrebbero generati mediante un template che genera anche dei link per accedere alla pagina relativa alla notifica
			mailer.sendMail(notifyTo.getEmail(), "HelpDesk - New attachment added", "New attachment added to your ticket");
		}
		
		return mapping.findForward("common.ok");
	}
	
	
	/* AJAX Request */
	public ActionForward loadTicket(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		int ticketID = Integer.parseInt(request.getParameter("itemID"));
		
		Ticket ticket = service.findTicketById(ticketID);
		
		request.setAttribute("item", ticket);
		
		return mapping.findForward("ticket.ticketbox");
	}
	
	
	/* AJAX Request */
	public ActionForward changeticketstatus(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		Map<String, String> mapstatus = new HashMap<String, String>();
		
		String ticketID = request.getParameter("ticketID");
		String status = request.getParameter("status");
		//SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy:kk:mm:ss");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd:kk:mm:ss");
		
		mapstatus.put("ticketid", ticketID);
		
		System.out.println("ticketid= "+mapstatus.get("ticketid"));
		
		mapstatus.put("status", status);
		mapstatus.put("closedate", sdf.format(new Date()));
		
		service.changeTicketStatus(mapstatus);

		return null;
	}
	
	/* AJAX Request */
	public ActionForward changeticketpriority(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		Map<String, String> mappriority = new HashMap<String, String>();
		
		String ticketID = request.getParameter("ticketID");
		String priority = request.getParameter("priority");
		
		mappriority.put("ticketid", ticketID);
		mappriority.put("priority", priority);
	
		service.changeTicketPriority(mappriority);
			
		return null;
	}
	
	/* AJAX Request */
	public ActionForward reloadticketattachments(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		TicketService service = factory.getTicketService();
		
		int ticketID = Integer.parseInt(request.getParameter("ticketID"));
		
		List<Attachment> attachments = service.findTicketById(ticketID).getAttachment();
		
		request.setAttribute("attachments", attachments);
		
		return mapping.findForward("ticket.reloadattachments");
	}
}
